/**
 * 
 */
package smallChanges.statements;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

import smallChanges.Tokenization.TokenSet;

public class MethodSignature extends StatementHeader implements IAccessNode
{
	// visibility
	private SCVisibility visibility;
	
	// modifiers
	private SCModifiers modifiers;
	
	// method name
	private String name;
	
	// return type
	private boolean isVoid;
	// returnType will be null for a constructor
	private SCType returnType;

	// formal parameters
	private List<SCFormalParameter> formalParamList=new LinkedList<SCFormalParameter>();
	
	// exceptions
	private List<String> exceptionList=new LinkedList<String>();
	
	public MethodSignature(TokenSet tokenSet) {
		super(tokenSet);
		setStmtType(METHOD_SIGNATURE);
	}
	
	/* (non-Javadoc)
     * @see smallChanges.statements.IMethodSignature#getSignature()
     */
	public String getSignature()
	{
	    return tokensInRange.getImage();
//		return (visibility==SCVisibility.PACKAGE_PRIVATE?"":visibility+" ") +
//		
//		(isAbstract()?" abstract":"") +
//		(isStatic()?"static ":"") +
//		(isSynchronized()?"synchronized ":"") +
//		(isFinal()?"final ":"") +
//		
//		(isVoid()?"void ":returnType+" ") +
//		
//		name + " ( "+
//		makeCommaSeparatedStringFromList(formalParamList)+
//		")"+
//		(exceptionList.size()>0?" throws "+makeCommaSeparatedStringFromList(exceptionList):"");
	}

	/* (non-Javadoc)
     * @see smallChanges.statements.IMethodSignature#toString()
     */
	public String toString() {
		return getSignature();
	}
	
	private static String makeCommaSeparatedStringFromList(List list) {
		StringBuffer buf=new StringBuffer();
		for (Object o : list) {
			buf.append(o.toString()+" , ");
		}
		if (buf.length()>=2) {
			buf.replace(buf.length()-2, buf.length(), "");
		}
		return buf.toString();
	}
	
	public int getNumFormalParams()
	{
	    return getFormalParameterList().size();
	}
	public int getNumExceptions()
	{
	    return getExceptionList().size();
	}
	public String getExceptionsImage()
    {
	    String result="";
	    for (String e : getExceptionList()) {
	        result += e+" ";
	    }
	    result=result.replaceAll(" +$", "");
	    return result;
    }
	public String getFormalParamsImage()
	{
	    String result="";
        for (SCFormalParameter f : getFormalParameterList()) {
            result += f+" ";
        }
        result=result.replaceAll(" +$", "");
        return result;
	}
	
	/* (non-Javadoc)
     * @see smallChanges.statements.IMethodSignature#getImage()
     */
	@Override
	public String getImage()
	{
		return getSignature();
	}
	
	@Override
    String toStringHelper(int depth)
    {
	    return getSignature();
    }

	/* (non-Javadoc)
     * @see smallChanges.statements.IMethodSignature#getName()
     */
	public String getName()
	{
		return name;
	}
	/* (non-Javadoc)
     * @see smallChanges.statements.IMethodSignature#setName(java.lang.String)
     */
	public void setName(String name)
	{
		this.name = name;
	}

	/* (non-Javadoc)
     * @see smallChanges.statements.IMethodSignature#isVoid()
     */
	public boolean isVoid()
	{
		return isVoid;
	}
	/* (non-Javadoc)
     * @see smallChanges.statements.IMethodSignature#setVoid(boolean)
     */
	public void setVoid(boolean isVoid)
	{
		this.isVoid = isVoid;
	}

	/* (non-Javadoc)
     * @see smallChanges.statements.IMethodSignature#getReturnType()
     */
	public SCType getReturnType()
	{
		return returnType;
	}
	/* (non-Javadoc)
     * @see smallChanges.statements.IMethodSignature#setReturnType(smallChanges.statements.SCType)
     */
	public void setReturnType(SCType returnType)
	{
		this.returnType = returnType;
	}

	/* (non-Javadoc)
     * @see smallChanges.statements.IMethodSignature#setVisibility(smallChanges.statements.SCVisibility)
     */
	public void setVisibility(SCVisibility visibility)
	{
		this.visibility=visibility;
	}

    /* (non-Javadoc)
     * @see smallChanges.statements.IMethodSignature#getVisibility()
     */
    public SCVisibility getVisibility()
    {
        return visibility;
    }

    /* (non-Javadoc)
     * @see smallChanges.statements.IMethodSignature#getModifiers()
     */
    public SCModifiers getModifiers()
    {
        return modifiers;
    }

    /* (non-Javadoc)
     * @see smallChanges.statements.IGetMethodSignature#isAbstract()
     */
	public boolean isAbstract()
	{
		return modifiers.isAbstract();
	}

	/* (non-Javadoc)
     * @see smallChanges.statements.IMethodSignature#isFinal()
     */
	public boolean isFinal()
	{
		return modifiers.isFinal();
	}

	/* (non-Javadoc)
     * @see smallChanges.statements.IMethodSignature#isStatic()
     */
	public boolean isStatic()
	{
		return modifiers.isStatic();
	}

	/* (non-Javadoc)
     * @see smallChanges.statements.IMethodSignature#isSynchronized()
     */
	public boolean isSynchronized()
	{
		return modifiers.isSynchronized();
	}

	/* (non-Javadoc)
     * @see smallChanges.statements.IMethodSignature#isTransient()
     */
	public boolean isTransient()
	{
		return modifiers.isTransient();
	}

	/* (non-Javadoc)
     * @see smallChanges.statements.IMethodSignature#isVolatile()
     */
	public boolean isVolatile()
	{
		return modifiers.isVolatile();
	}

	/* (non-Javadoc)
     * @see smallChanges.statements.IMethodSignature#setAbstract(boolean)
     */
	public void setAbstract(boolean isAbstract)
	{
		modifiers.setAbstract(isAbstract);
	}

	/* (non-Javadoc)
     * @see smallChanges.statements.IMethodSignature#setFinal(boolean)
     */
	public void setFinal(boolean isFinal)
	{
		modifiers.setFinal(isFinal);
	}

	/* (non-Javadoc)
     * @see smallChanges.statements.IMethodSignature#setStatic(boolean)
     */
	public void setStatic(boolean isStatic)
	{
		modifiers.setStatic(isStatic);
	}

	/* (non-Javadoc)
     * @see smallChanges.statements.IMethodSignature#setSynchronized(boolean)
     */
	public void setSynchronized(boolean isSynchronized)
	{
		modifiers.setSynchronized(isSynchronized);
	}

	/* (non-Javadoc)
     * @see smallChanges.statements.IMethodSignature#setTransient(boolean)
     */
	public void setTransient(boolean isTransient)
	{
		modifiers.setTransient(isTransient);
	}

	/* (non-Javadoc)
     * @see smallChanges.statements.IMethodSignature#setVolatile(boolean)
     */
	public void setVolatile(boolean isVolatile)
	{
		modifiers.setVolatile(isVolatile);
	}

	/* (non-Javadoc)
     * @see smallChanges.statements.IMethodSignature#setModifiers(smallChanges.statements.SCModifiers)
     */
	public void setModifiers(SCModifiers modifiers)
	{
		this.modifiers=modifiers;
	}

	/* (non-Javadoc)
     * @see smallChanges.statements.IMethodSignature#addFormalParameter(smallChanges.statements.SCFormalParameter)
     */
	public void addFormalParameter(SCFormalParameter formalParameter)
	{
		if (formalParamList==null)
			formalParamList=new LinkedList<SCFormalParameter>();
		formalParamList.add(formalParameter);
	}

	/* (non-Javadoc)
     * @see smallChanges.statements.IMethodSignature#addExceptionThrown(java.lang.String)
     */
	public void addExceptionThrown(String exceptionName)
	{
		if (exceptionList==null)
			exceptionList=new LinkedList<String>();
		exceptionList.add(exceptionName);
	}
	
    /* (non-Javadoc)
     * @see smallChanges.statements.IMethodSignature#getFormalParameterIterator()
     */
    public Iterator<SCFormalParameter> getFormalParameterIterator()
    {
    	return formalParamList.iterator();
    }
    
    /* (non-Javadoc)
     * @see smallChanges.statements.IMethodSignature#getFormalParameterList()
     */
    public List<SCFormalParameter> getFormalParameterList()
    {
    	return formalParamList;
    }
    
    /* (non-Javadoc)
     * @see smallChanges.statements.IMethodSignature#getExceptionList()
     */
    public List<String> getExceptionList()
    {
        return exceptionList;
    }

    public String getReturnTypeAsString()
    {
    	if(returnType != null)
    	{
    		return returnType.toString();
    	}
    	return null;
    }

    // produce a formal parameter list that only contains types and commmas
    public String getTypeOnlyFormalParamsImage()
    {
    	String retVal = new String();

    	Iterator<SCFormalParameter> iter = formalParamList.iterator();

    	while(iter.hasNext())
    	{
    		SCFormalParameter param = iter.next();
    		retVal += param.getType();
    		if( param.isArrayType() )
    		{
    			retVal += "[]";
    		}
    	}
    	return retVal;
    }
}